package com.um.springboot.starter.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.um.springboot.starter.constants.SmsConsts;
import com.um.springboot.starter.properties.AliyunSmsProperties;
import com.um.springboot.starter.service.SmsService;
import com.um.springboot.starter.utils.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 阿里云短信（https://www.aliyun.com/）
 *
 * @author 甘天伟
 * @since 2024/5/7
 * 版权所有 广州优匠科技有限公司
 */
@Slf4j
@Primary
@Component(SmsConsts.ALIYUN_IMPL)
public class AliyunSmsServiceImpl implements SmsService {

    @Autowired
    AliyunSmsProperties aliyunSmsProperties;

    /**
     * 发送短信
     *
     * @param mobileAreaCode 国家代码
     * @param mobile         手机号
     * @param template       模板
     * @param params         模板参数
     * @param customSmsProps 自定义配置
     * @return 是否成功
     */
    @Override
    public boolean send(String mobileAreaCode, String mobile, String template, LinkedHashMap<String, String> params, Object customSmsProps) {
        AliyunSmsProperties props = ObjectUtil.defaultIfNull((AliyunSmsProperties) customSmsProps, aliyunSmsProperties);

        IClientProfile profile = DefaultProfile.getProfile(props.getRegionId(), props.getAccessKeyId(), props.getAccessKeySecret());
        IAcsClient acsClient = new DefaultAcsClient(profile);

        CommonRequest request = new CommonRequest();
        request.setSysProtocol(ProtocolType.HTTPS);
        request.setSysMethod(MethodType.POST);
        //域名，请勿修改
        request.setSysDomain("dysmsapi.aliyuncs.com");
        //API版本号，请勿修改
        request.setSysVersion("2017-05-25");
        //API名称，请勿修改
        request.setSysAction("SendSms");

        String signName, templateCode;
        if (StrUtil.isBlank(mobileAreaCode) || ReUtil.isMatch("(\\+|00)?86", mobileAreaCode)) { // 国内短信
            signName = props.getSignName();
            templateCode = props.getTemplateCodes().get(template);
        } else { // 国际短信
            signName = props.getSignNameIntl();
            templateCode = props.getTemplateCodesIntl().get(template);
        }

        String phone = mobileAreaCode + mobile;
        request.putQueryParameter("PhoneNumbers", phone);
        request.putQueryParameter("SignName", signName);
        request.putQueryParameter("TemplateCode", templateCode);
        request.putQueryParameter("TemplateParam", JSONUtil.toJSONString(params));

        try {
            CommonResponse response = acsClient.getCommonResponse(request);
            if (null == response || null == response.getData()) {
                log.error("阿里云发送短信未响应: [{}]", phone);
                return false;
            }

            Map map = JSONUtil.parseJSONToMap(response.getData());
            if (!Objects.equals(map.get("Code"), "OK")) {
                log.error("阿里云发送短信失败: [{}]{}", phone, response.getData());
                return false;
            }

            log.info("阿里云发送短信结果: [{}]{}", phone, response.getData());
            return true;
        } catch (Exception e) {
            log.error(StrUtil.format("阿里云发送短信错误: [{}]", phone) , e);
            return false;
        }
    }
}
